package com.zyz.framework.advice;


import com.zyz.common.annotation.FileData;
import com.zyz.common.core.page.Page;

import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.List;

/**
 * BodyAdviceKit
 *
 * @author zyz
 * @date 2021年3月2日
 */
public class BodyAdviceKit {

    /**
     * 处理简单对象
     *
     * @param body
     * @param annotationClass
     * @param bodyAdvice
     * @return void
     * @throws Exception
     * @author zyz
     * @date 2021年3月2日
     */
    public static void resetSimpleObject(Object body, Class<? extends Annotation> annotationClass,
                                         BodyAdvice bodyAdvice) throws Exception {

        if (body == null) {
            return;
        }

        Class<? extends Object> bodyClass = body.getClass();

        if (!bodyClass.isAnnotationPresent(annotationClass)) {
            return;
        }

        resetObject(body, annotationClass, bodyAdvice, bodyClass);

    }

    /**
     * 处理复杂对象
     *
     * @param body
     * @param annotationClass
     * @param bodyAdvice
     * @return void
     * @throws Exception
     * @author zyz
     * @date 2021年3月2日
     */
    public static void resetComplexObject(Object body, Class<? extends Annotation> annotationClass,
                                          BodyAdvice bodyAdvice) throws Exception {

        if (body == null) {
            return;
        }

        if (body instanceof String) {
            return;
        }

        if (body instanceof Page<?>) {
            resetComplexObjectList(((Page<?>) body).getList(), annotationClass, bodyAdvice);
            return;
        }

        if (body instanceof List<?>) {
            resetComplexObjectList(((List<?>) body), annotationClass, bodyAdvice);
            return;
        }

        Class<? extends Object> bodyClass = body.getClass();

        if (bodyClass.isArray()) {
            int length = Array.getLength(body);
            for (int i = 0; i < length; i++) {
                resetComplexObject(Array.get(body, i), annotationClass, bodyAdvice);
            }
            return;
        }

        if (!bodyClass.isAnnotationPresent(FileData.class)) {
            return;
        }

        resetObject(body, annotationClass, bodyAdvice, bodyClass);

    }

    private static void resetComplexObjectList(List<?> bodyList, Class<? extends Annotation> annotationClass,
                                               BodyAdvice bodyAdvice) throws Exception {
        for (Object object : bodyList) {
            resetComplexObject(object, annotationClass, bodyAdvice);
        }

    }

    private static void resetObject(Object body, Class<? extends Annotation> annotationClass, BodyAdvice bodyAdvice,
                                    Class<? extends Object> bodyClass) throws IllegalAccessException, Exception {
        Field[] bodyFields = bodyClass.getDeclaredFields();
        for (Field field : bodyFields) {
            if (field.isAnnotationPresent(annotationClass)) {
                field.setAccessible(true);
                Object fieldValue = field.get(body);
                if (fieldValue == null) {
                    continue;
                }
                if (fieldValue instanceof String) {
                    field.set(body, bodyAdvice.getAdviceFieldValue(fieldValue));
                } else if (fieldValue instanceof List) {
                    resetComplexObjectList(((List<?>) fieldValue), annotationClass, bodyAdvice);
                } else {
                    resetComplexObject(fieldValue, annotationClass, bodyAdvice);
                }
            }
        }
    }

}
